<template>
  <view class="container">
    <uni-section title="上传试题" type="line" padding>
      <uni-steps :options="stepList" :active="active" />
    </uni-section>
    <view class="question_type" v-show="active == 0">
      <uni-section title="题号" type="line">
        <uni-number-box :min="1" :max="15" :value="state.order"></uni-number-box>
      </uni-section>
      <uni-section title="知识点" type="line" class="knowledgeSelect">
        <uni-data-select
          :localdata="knowledgeListSelect"
          placeholder="请选择知识点"
          emptyTips="知识点加载失败"
          @change="onKnowledgeChange"
        ></uni-data-select>
      </uni-section>
      <uni-section title="题型" type="line">
        <radio-group @change="type_change">
          <label
            class="uni-list-cell uni-list-cell-pd"
            v-for="(item, index) in type_list"
            :key="index"
          >
            <view>
              <radio :value="item.value" :checked="item.checked" style="transform: scale(0.6)" />{{
                item.name
              }}
            </view>
          </label>
        </radio-group>
      </uni-section>
    </view>
    <view class="main" v-show="active == 1">
      <view class="uni-textarea content">
        <textarea
          @blur="bindTextAreaBlurContent"
          :value="state.content"
          placeholder-style="color:#6f6f6f"
          placeholder="输入题干"
          :maxlength="maxLengthContent"
        />
        <view class="ocr">
          <uni-file-picker
            limit="1"
            :list-styles="listStyles"
            file-extname="png,jpg"
            :auto-upload="false"
            ref="ocrfileRef"
            :sourceType="ocrSourceType"
            @select="ocrSelect"
          >
            <button size="mini" type="primary" class="mini-btn">OCR识别</button>
          </uni-file-picker>
        </view>
      </view>
      <text>插图</text>
      <uni-file-picker
        limit="9"
        v-model:value="state.imageValueContent"
        :auto-upload="false"
        :sourceType="sourceType"
        :image-styles="imageStyles"
        fileMediatype="image"
        file-extname="png,jpg"
        mode="grid"
        @select="selectContent"
        @delete="deleteContent"
        ref="contentFileRef"
      />
    </view>
    <view class="main" v-show="active == 2">
      <view class="uni-textarea content">
        <textarea
          @blur="bindTextAreaBlurAnswer"
          :value="state.answer"
          placeholder-style="color:#6f6f6f"
          placeholder="输入答案"
          :maxlength="maxLengthAnswer"
        />
        <view class="ocr">
          <uni-file-picker
            limit="1"
            :list-styles="listStyles"
            file-extname="png,jpg"
            :auto-upload="false"
            ref="ocrfileAnswerRef"
            :sourceType="ocrSourceType"
            @select="ocrSelect"
          >
            <button size="mini" type="primary" class="mini-btn">OCR识别</button>
          </uni-file-picker>
        </view>
      </view>
      <text>插图</text>
      <uni-file-picker
        limit="9"
        :value="state.imageValueAnswer"
        :sourceType="sourceType"
        :image-styles="imageStyles"
        fileMediatype="image"
        file-extname="png,jpg"
        mode="grid"
        @select="selectAnswer"
        @delete="deleteAnswer"
        ref="answerFileRef"
      />
    </view>
    <view class="main" v-show="active == 3">
      <view class="uni-textarea content">
        <textarea
          @blur="bindTextAreaBlurExplain"
          @input="onInputExplain"
          :value="state.explain"
          placeholder-style="color:#6f6f6f"
          placeholder="输入解析"
          :maxlength="maxLengthExplain"
        />
        <view class="ocr">
          <uni-file-picker
            limit="1"
            :list-styles="listStyles"
            file-extname="png,jpg"
            :auto-upload="false"
            ref="ocrfileExplainRef"
            :sourceType="ocrSourceType"
            @select="ocrSelect"
          >
            <button size="mini" type="primary" class="mini-btn">OCR识别</button>
          </uni-file-picker>
        </view>
      </view>
      <text>插图</text>
      <uni-file-picker
        limit="9"
        :value="state.imageValueExplain"
        :sourceType="sourceType"
        :image-styles="imageStyles"
        fileMediatype="image"
        file-extname="png,jpg"
        mode="grid"
        @select="selectExpalin"
        @delete="deleteExpalin"
        ref="explainFileRef"
      />
    </view>
    <view class="two_button">
      <button @tap="onNextStepClick" class="mini-btn" size="mini" type="primary">next</button>
      <button v-if="active == 3" @tap="onSubmitClick" class="mini-btn" size="mini" type="primary">
        submit
      </button>
    </view>
  </view>
</template>

<script setup lang="ts">
import { ref, reactive } from 'vue'
import { onLoad } from '@dcloudio/uni-app'
import type { ExaminationPaperItem, KnowledgeItem, QuestionTypeItem } from '@/types/home'
import { getKnowledgeAPI, postOneQuestionToExamPaperAPI, postOcrAPI } from '@/services/home'
import UniSteps from '@dcloudio/uni-ui/lib/uni-steps/uni-steps.vue'
import UniDataSelect from '@dcloudio/uni-ui/lib/uni-data-select/uni-data-select.vue'
import UniFilePicker from '@dcloudio/uni-ui/lib/uni-file-picker/uni-file-picker.vue'
import UniSection from '@dcloudio/uni-ui/lib/uni-section/uni-section.vue'
import { uploadFile } from '@/utils/http'
const ocrSourceType = ['camera']
const ocrfileRef = ref()
const ocrfileAnswerRef = ref()
const ocrfileExplainRef = ref()
const contentFileRef = ref()
const answerFileRef = ref()
const explainFileRef = ref()
const maxLengthContent = 2500
const maxLengthAnswer = 1000
const maxLengthExplain = 2500
// 真正有用的是id和subject，其中subject用于获取该学科是知识点，关联题目
const examination_paper = reactive<ExaminationPaperItem>({
  id: 0,
  publish_time: '',
  title: '',
  is_joint: true,
  subject: 1,
  open_level: 'public',
  online: true,
  grade: 3,
  expiration: '',
})
const listStyles = {
  // 是否显示边框
  border: true,
  // 是否显示分隔线
  dividline: true,
  // 线条样式
  borderStyle: {
    width: 1,
    color: 'blue',
    radius: 5,
    style: 'solid',
  },
}
// 上传图片的样式
const imageStyles = {
  width: 60,
  height: 60,
}
const sourceType = ['album', 'camera']
// 获取知识点api的参数
let subjectParams = {
  subject_id: examination_paper.subject,
}
// 存放知识点下拉菜单的专用列表
const knowledgeListSelect = ref<SelectItem[]>([])
// 获取该学科的知识点
const knowledgeList = ref<KnowledgeItem[]>([])
const getKnowledgeData = async () => {
  const res = await getKnowledgeAPI(subjectParams)
  if (Array.isArray(res.results) && res.results.length > 0) {
    knowledgeList.value = res.results
    console.log('获取知识点：', knowledgeList.value)
    for (let i = 0; i < res.results.length; i++) {
      let item = res.results[i]
      knowledgeListSelect.value.push({ value: item.id, text: item.name })
    }
  } else {
    uni.showToast({ icon: 'error', title: '获取失败' })
  }
}
type SelectItem = {
  value: number
  text: string
}

const onKnowledgeChange = (value: number) => {
  console.log('选中了知识点', value)
  state.knowledgepoint = value
}
// 存放各种散乱的变量
const state = reactive<any>({
  imageValueContent: '',
  imageValueAnswer: '',
  imageValueExplain: '',
  fileListContent: [],
  fileListAnswer: [],
  fileListExplain: [],
  pictures: '',
  pictures_answer: '',
  pictures_explain: '',
  pictures_scale: '',
  pictures_answer_scale: '',
  pictures_explain_scale: '',
  content: '',
  answer: '',
  explain: '',
  type: 1,
  order: 1,
  knowledgepoint: 0,
})
const type_list = ref<QuestionTypeItem[]>([
  { name: '选择题', value: '1', checked: true },
  { name: '填空题', value: '2', checked: false },
  { name: '多选题', value: '3', checked: false },
  { name: '判断题', value: '4', checked: false },
])
const active = ref<number>(0)
const stepList = [{ title: '基本信息' }, { title: '题干' }, { title: '答案' }, { title: '解析' }]
// 题型改变了，修改题目的题型
const type_change = (e: any) => {
  console.log('题型改变：', e.target.value)
  state.type = e.target.value
}
// 分离图片返回的结果，以#为分离标志
const splitByHash = (str: string) => {
  // 正则表达式匹配'#'之前的所有字符和'#'之后的所有字符
  const regex = /^(.*?)#(.*?)$/
  // 执行匹配
  const matches = str.match(regex)
  // 如果匹配成功，matches[1] 是'#'之前的部分，matches[2] 是'#'之后的部分
  if (matches) {
    return [matches[1], matches[2]]
  } else {
    // 如果没有找到'#'，返回原始字符串和空字符串
    return [str, '']
  }
}
// 把图片数组里的内容转换成字符串, 发送给服务器，返回该图片在服务器的url（不带http开头）
const convertImageArray2String = async (fileList: any) => {
  // console.log('要发送图片转换了', fileList)
  let fileListString = ''
  let scale = ''
  // 除图片之外的其他参数
  let formData = {
    no_http: true,
    need_width_height: true,
  }
  for (let i = 0; i < fileList.length; i++) {
    const res = await uploadFile('/uploadImage/', fileList[i], formData)
    console.log('收到后端图片：', res)
    if (res.code === 200) {
      const [image_url, image_scale] = splitByHash(res.data.results)
      console.log('image_url', image_url)
      console.log('image_scale', image_scale)
      scale += image_scale + '-'
      fileListString += image_url + '-'
    } else {
      uni.showToast({ icon: 'error', title: '上传图片错误!' })
    }
  }
  if (fileListString.length > 0) {
    fileListString = fileListString.substring(0, fileListString.length - 1)
  }
  if (scale.length > 0) {
    scale = scale.substring(0, scale.length - 1)
  }
  return { url: fileListString, scale: scale }
}
// 提交试题
const onSubmitClick = async () => {
  // 检测题干、答案、解析是否为空
  if (checkEmpty() == false) {
    uni.showToast({ icon: 'error', title: '存在空值!' })
    return 0
  } else {
    uni.showToast({ icon: 'success', title: '数据正常!' })
  }
  // 把图片数组转换成字符串（经过服务器端，返回不带https开头的url）
  let content_result = await convertImageArray2String(state.fileListContent)
  state.pictures = content_result['url']
  state.pictures_scale = content_result['scale']
  let answer_result = await convertImageArray2String(state.fileListAnswer)
  state.pictures_answer = answer_result['url']
  state.pictures_answer_scale = answer_result['scale']
  let expain_result = await convertImageArray2String(state.fileListExplain)
  state.pictures_explain = expain_result['url']
  state.pictures_explain_scale = expain_result['scale']
  const param_question = {
    content: state.content,
    answer: state.answer,
    explain: state.explain,
    reference: examination_paper.title,
    type: state.type,
    open_level: 'public',
    online: true,
    order: state.order,
    // 选择题1分，填空题2分，跟随题型的值
    bank_point: state.tpye,
    knowledgepoint: state.knowledgepoint,
    pictures: state.pictures,
    pictures_answer: state.pictures_answer,
    pictures_explain: state.pictures_explain,
    pictures_scale: state.pictures_scale,
    pictures_answer_scale: state.pictures_answer_scale,
    pictures_explain_scale: state.pictures_explain_scale,
  }
  console.log('发送给后端的题目参数：', param_question)
  const params_data = {
    question_dic: param_question,
    paper_id: examination_paper.id,
  }
  //向后台发送提交题目的的请求
  const res = await postOneQuestionToExamPaperAPI(params_data)
  console.log('提交题目结果：', res)
  if (res.code === 200) {
    uni.showToast({ icon: 'success', title: '提交成功' })
    clearQuestionParam()
  } else if (res.code === 1099) {
    uni.showToast({ icon: 'error', title: '提交失败' })
  } else {
    uni.showToast({ icon: 'error', title: '提交错误' })
  }
}
//清空题目所有的参数
const clearQuestionParam = () => {
  console.log('clear question')
  contentFileRef.value.clearFiles()
  answerFileRef.value.clearFiles()
  explainFileRef.value.clearFiles()
  state.content = ''
  state.answer = ''
  state.explain = ''
  state.pictures = ''
  state.pictures_answer = ''
  state.pictures_explain = ''
  state.pictures_scale = ''
  state.pictures_answer_scale = ''
  state.pictures_explain_scale = ''
  active.value = 0
}
// 下一步按钮点击事件
const onNextStepClick = () => {
  console.log('下一步')
  if (state.knowledgepoint == 0) {
    uni.showToast({ icon: 'error', title: '先选择知识点' })
    return 0
  }
  if (active.value < stepList.length - 1 && state.knowledgepoint > 0) {
    active.value += 1
  } else {
    if (active.value == stepList.length - 1 && state.knowledgepoint > 0) {
      active.value = 0
    }
  }
}
// 多行文本框题干输入事件
const bindTextAreaBlurContent = (e: any) => {
  console.log(e.detail.value)
  state.content = e.detail.value
}
// 多行文本框答案输入事件
const bindTextAreaBlurAnswer = (e: any) => {
  console.log(e.detail.value)
  state.answer = e.detail.value
}
// 多行文本框解析输入事件
const bindTextAreaBlurExplain = (e: any) => {
  console.log(e.detail.value)
  state.explain = e.detail.value
}
// 多行文本框输入文本事件
const onInputExplain = (e: any) => {
  state.explain = e.detail.value
}
// 页面加载
onLoad(async (opts: any) => {
  examination_paper.id = parseInt(decodeURIComponent(opts.paper_id))
  examination_paper.subject = parseInt(decodeURIComponent(opts.subject_id))
  examination_paper.title = decodeURIComponent(opts.paper_title)
  console.log('试卷id', examination_paper.id)
  console.log('学科id', examination_paper.subject)
  getKnowledgeData()
})
// ocr选择图片
const ocrSelect = async (e: any) => {
  console.log('ocr选择图片', e.tempFilePaths[0])
  const formData = {}
  const res = await uploadFile('/ImageOcrAPIView/', e.tempFilePaths[0], formData)
  console.log('ocr识别结果：', res)
  if (res.code == 200) {
    console.log('ocr ok!')
    if (active.value == 1) {
      state.content += res.data.results
    } else if (active.value == 2) {
      state.answer += res.data.results
    } else if (active.value == 3) {
      state.explain += res.data.results
    } else {
      uni.showToast({ icon: 'error', title: 'active error!' })
    }
  } else {
    uni.showToast({ icon: 'error', title: 'ocr fail!' })
  }
}
// 选择照片并上传到服务器，返回该照片在服务器的url
const selectContent = (e: any) => {
  console.log('选择文件：', e.tempFilePaths)
  e.tempFilePaths.forEach((tempFilePath: any) => {
    state.fileListContent.push(tempFilePath)
  })
  console.log('选择后图片列表：', state.fileListContent)
}
//删除照片
const deleteContent = (e: any) => {
  console.log('删除', e)
  for (let i = 0; i < state.fileListContent.length; i++) {
    if (state.fileListContent[i] === e.tempFilePath) {
      state.fileListContent.splice(i, 1)
      break
    }
  }
  // console.log('删除后图片列表：', state.fileListContent)
}
// 选择照片并上传到服务器，返回该照片在服务器的url
const selectAnswer = (e: any) => {
  e.tempFilePaths.forEach((tempFilePath: any) => {
    state.fileListAmswer.push(tempFilePath)
  })
  // console.log('选择后图片列表：', state.fileListAmswer)
}
//删除答案的照片
const deleteAnswer = (e: any) => {
  console.log('删除', e)
  for (let i = 0; i < state.fileListAnswer.length; i++) {
    if (state.fileListAnswer[i] === e.tempFilePath) {
      state.fileListAnswer.splice(i, 1)
      break
    }
  }
  console.log('删除后图片列表：', state.fileListAnswer)
}
// 选择照片并上传到服务器，返回该照片在服务器的url
const selectExpalin = (e: any) => {
  e.tempFilePaths.forEach((tempFilePath: any) => {
    state.fileListExplain.push(...tempFilePath)
  })
  // console.log('选择后图片列表：', state.fileListExplain)
}
//删除解析插图
const deleteExpalin = (e: any) => {
  console.log('删除', e)
  for (let i = 0; i < state.fileListExplain.length; i++) {
    if (state.fileListExplain[i] === e.tempFilePath) {
      state.fileListExplain.splice(i, 1)
      break
    }
  }
  console.log('删除后图片列表：', state.fileListExplain)
}
// 检查题干、答案、解析是否为空, 空返回true；非空返回false
const checkEmpty = () => {
  let flag = true
  if (state.content === '' || state.answer === '' || state.explain === '') {
    flag = false
  }
  // console.log('空值flag:', flag)
  return flag
}
</script>

<style lang="scss">
.container {
  margin: 5rpx;
  padding: 5rpx;
  .steps {
    margin: 1rpx;
  }
}
.main {
  display: flex;
  flex-direction: column;
}
.content {
  border: 2rpx;
  border-color: gray;
  border-radius: 5rpx;
  border-style: solid;
}
.question_type {
  display: flex;
  flex-flow: column wrap;
  justify-content: center;
  align-items: flex-start;
}
.knowledgeSelect {
  font-size: 10rpx;
}
.uni-textarea {
  font-size: 28rpx;
}
.two_button {
  display: flex;
  flex-flow: row nowrap;
  justify-content: space-between;
}
</style>
